package aterrizar;

import java.util.Date;

import aterrizar.exceptions.AnticipacionInvalidaException;
import aterrizar.exceptions.AsientoNoDisponibleException;
import aterrizar.exceptions.AsientoYaLiberadoException;
import aterrizar.exceptions.ReservaInvalidaException;
import configuracion.ContenedorPropiedades;

public class Reserva {
	
	public enum Estado {
		CREADO,
		RESERVADO,
		CANCELADO,
	};
	
	private float porcentajeSenia = Float.valueOf("0.15");
	private double importe;
	private Pasajero pasajero;
	private Vuelo vueloReservado;
	private Asiento asientoReservado;
	private Date diaReserva = new Date();
	private String numeroReserva;
	private Estado estado;

	public Reserva(Vuelo vuelo, Pasajero pasajero, Asiento asiento)
			throws ReservaInvalidaException {

		this.vueloReservado = vuelo;
		this.pasajero = pasajero;
		this.asientoReservado = asiento;
		
		setEstado(Estado.CREADO);

		String propiedadPorcentajeSenia = ContenedorPropiedades
				.getPropiedad("porcentajeSenia");
		if (propiedadPorcentajeSenia != null) {
			try {
				porcentajeSenia = Float.valueOf(propiedadPorcentajeSenia);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}

		Anticipacion anticipacion;
		try {
			anticipacion = new Anticipacion(diaReserva, vuelo.getFechaPartida() );
		} catch (AnticipacionInvalidaException e) {
			throw new ReservaInvalidaException("El vuelo ya partio.");
		}

		this.importe = vueloReservado.getPrecio(asientoReservado.getClase(),anticipacion) * porcentajeSenia;
	}

	@Override
	public boolean equals(Object obj) {
		if ( this == obj ) return true;
		if ( !(obj instanceof Reserva) ) return false;
		Reserva reserva = (Reserva) obj;
		return reserva.pasajero.equals(pasajero) && 
		reserva.vueloReservado.equals(vueloReservado) &&
		reserva.asientoReservado.equals(asientoReservado);
	}

	private void setEstado(Estado estado) {
		this.estado = estado;
	}
	
	public Estado getEstado() {
		return estado;
	}

	public Pasajero getPasajero() {
		return pasajero;
	}

	public Vuelo getVuelo() {
		return vueloReservado;
	}

	public Asiento getAsiento() {
		return asientoReservado;
	}
	
	public Date getDiaReserva(){
		return diaReserva;
	}

	public void reservar() throws AsientoNoDisponibleException {
		asientoReservado.reservar(this);
		vueloReservado.agregarReserva(this);
		setEstado(Estado.RESERVADO);
	}

	public double getImporte() {
		return importe;
	}

	public double cancelar() throws AsientoYaLiberadoException {
		asientoReservado.liberar();
		vueloReservado.cancelarReserva(this);
		setEstado(Estado.CANCELADO);
		return calcularImporte();
	}

	private double calcularImporte() {
		Date hoy = new Date();

		long diferenciaDias = (hoy.getTime() - diaReserva.getTime())
				/ (1000 * 60 * 60 * 24);

		if (diferenciaDias <= 2) {
			// dentro de las 48 horas.
			return importe;
		}

		if (diferenciaDias <= 7) {
			// en la misma semana.
			return importe / 2;
		}

		return 0;
	}

	public String getNumeroReserva() {
		return numeroReserva;
	}

	public void setNumeroReserva(String numeroReserva) {
		this.numeroReserva = numeroReserva;
	}


}
